package util

import (
	"container/list"
	"sync"
)

type BlockingDeque[T any] struct {
	link *list.List
	lock *sync.Mutex
}

func NewBlockingDeque[T any]() *BlockingDeque[T] {
	l := &sync.Mutex{}
	return &BlockingDeque[T]{
		link: list.New(),
		lock: l,
	}
}

func (d *BlockingDeque[T]) PushFront(t T) {
	d.lock.Lock()
	defer d.lock.Unlock()
	d.link.PushFront(t)

}

func (d *BlockingDeque[T]) TakeFront() (T, bool) {
	d.lock.Lock()
	defer d.lock.Unlock()
	if d.link.Len() == 0 {
		var t T
		return t, false
	}
	return d.link.Remove(d.link.Front()).(T), true
}
